using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Game;
using IQIGame.Onigao.Logic;
using LFloatMath.Math;
using UnityEngine;
using Random = LFloatMath.Math.Random;

namespace IQIGame.Onigao.GamePlay
{
    public class UnitView : TEntity, IFormulaObject
    {
        public EUnitType unitType;
        public int configID;

        public int GUID;
        public int teamIndex;
        public int lv = 10;
        public int skinID;

        public UnitViewProperty property;

        public string roleName => this.property.roleName;
        public string resPath => this.property.resPath;
        public int entityType => this.property.entityType;
        public float radius => this.property.radius;
        public string name => this.property.name;
        public string widgetPath => this.property.widgetPath;
        
        public IReadOnlyList<int> weaknessTypeList => this.property.weaknessTypeList;
        public string battleHeadIconPath => this.property.battleHeadIconPath;

        public EDamageType weaknessType; // 弱点 复合枚举
        public int weaknessPoint;
        public int maxWeaknessPoint;

        private LVector2 mPos;
        private LVector2 mForward;

        public bool disposed = false;
        
        public LVector2 pos
        {
            get => this.mPos;
            set
            {
                this.mPos = value;

                var rColComp = this.GetComponent<CollisionViewComponent>(ETComponentType.CollisionViewComponent);
                if (rColComp != null && rColComp.proxy != null)
                {
                    rColComp.proxy.pos = this.mPos;
                }
            }
        }

        public LVector2 forward
        {
            get => this.mForward == LVector2.zero ? LVector2.up : this.mForward;
            set { this.mForward = value; }
        }

        public bool IsDead() => this.Exists<DeadViewComponent>(ETComponentType.DeadViewComponent);

        public bool CheckDead()
        {
            var rAttr = this.GetComponent<AttributeViewComponent>(ETComponentType.AttributeViewComponent);
            return rAttr != null && rAttr.Get(EAttributeType.Hp) <= 0;
        }

        protected override void OnDispose()
        {
            this.disposed = true;
        }

        public async virtual UniTask InitializeView()
        {
            await this.GetComponent<UnitViewComponent>(ETComponentType.UnitViewComponent).Initialize();
            this.GetComponent<BattleAnimationComponent>(ETComponentType.BattleAnimationComponent).Initialize();
            this.GetComponent<BattleTimelineComponent>(ETComponentType.BattleTimelineComponent).Initialize();
            this.GetComponent<SkillViewComponent>(ETComponentType.SkillViewComponent).OnEnable();
            this.disposed = false;
        }

        #region Formula Func

        public virtual AttributeProperty GetAttr()
        {
            return this.GetComponent<AttributeViewComponent>(ETComponentType.AttributeViewComponent).attr;
        }

        public Random GetBattleRandom()
        {
            throw new System.NotImplementedException();
        }

        public virtual IEnumerable<IFormulaObject> GetUnits(int nTeamIndex)
        {
            if (nTeamIndex < 0)
            {
                return BattleManager.Instance.ctrl.data.units;
            }
            else
            {
                if (BattleManager.Instance.ctrl.data.teams.TryGetValue(nTeamIndex, out var rTeam))
                {
                    return rTeam.units;
                }
            }
            return null;
        }
        
        public int GetTeamIndex() => this.teamIndex;
        
        public virtual int GetBuffStack(int buffID)
        {
            var nStack = 0;
            var rBuffComp = this.GetComponent<BuffViewComponent>(ETComponentType.BuffViewComponent);
            for (int i = 0; i < rBuffComp.buffs.Count; i++)
            {
                var rBuff = rBuffComp.buffs[i];
                if (rBuff.buffID == buffID)
                {
                    nStack = rBuff.stack;
                    break;
                }
            }
            return nStack;
        }
        
        public virtual T GetCustomProperty<T>(ECustomProperty propertyType)
        {
            return this.GetComponent<CustomPropertyViewComponent>(ETComponentType.CustomPropertyViewComponent).GetProperty<T>(propertyType);
        }

        public virtual LVector2 GetPos() => this.pos;

        #endregion
    }

    public class UnitViewProperty
    {
        public string roleName = "";
        public string resPath = "";
        public int entityType;
        public float radius;
        public IReadOnlyList<int> weaknessTypeList;
        public string battleHeadIconPath;
        public string dialog;
        public string name;
        public string widgetPath;
    }
}